import javax.imageio.ImageIO;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

/**
 * Created with IntelliJ IDEA.
 * User: Marcin
 * Date: 03.05.13
 * Time: 20:25
 * To change this template use File | Settings | File Templates.
 */
public abstract class Agent {

    private String imgPath = "/agents/roboArrow.png";

    public static final int DEFAULT_NUMBER_OF_PARTICLES = 1000;

    protected Map map;

    protected double rotation;

    protected List<Particle> particles;

    protected List<Point> laserShoots;

    protected Image img;

    public Agent(Map map) {
        this(DEFAULT_NUMBER_OF_PARTICLES, map);
    }

    public Agent(int numberOfParticles, Map map) {
        this.map = map;
        this.laserShoots = new ArrayList<Point>();
        particles = new ArrayList<Particle>(numberOfParticles);
        while (true) {
            Particle p = new Particle();
            if (!map.isWall(p.getX(), p.getY())) {
                particles.add(p);
                if (particles.size() == numberOfParticles) {
                    break;
                }
            }
        }

//        java.net.URL imgURL = getClass().getResource(imgPath);
//        if (imgURL == null) {
//            System.err.println("Couldn't find file: " + imgPath);
//        }

        URL imgURL = getClass().getResource(imgPath);
        if (imgURL == null) {
            System.err.println("Couldn't find file: " + imgPath);
        }
        System.out.println(imgURL.getPath());
        try {
            this.img = ImageIO.read(getClass().getResourceAsStream(imgPath));
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }


    }





    public abstract void move(Direction direction, double rotation, double moveNoiseParam, double laserNoiseParam, int sigma, int laserSize);

    public void rotate(double rotation, double rotationNoiseParam) {
        this.rotation += rotation % (2 * Math.PI);
        //TODO tutaj dodac szum rotacji rotationNoiseParam -> zakres <0.01 - 1>
        Random r = new Random();
        double param = (r.nextGaussian() * rotationNoiseParam);
        for (Particle particle : particles) {
            particle.setRotation(particle.getRotation() + ((rotation + param) % (2 * Math.PI)));
        }
    }

    public abstract void sense(int laserSize);

    public List<Particle> getParticles() {
        return particles;
    }

    public Map getMap() {
        return this.map;
    }

    public double getRotation() {
        return rotation;
    }

    public Image getImg() {
        return this.img;
    }

    public List<Point> getLaserShoots() {
        return laserShoots;
    }

    public void setLaserShoots(List<Point> laserShoots) {
        this.laserShoots = laserShoots;
    }

    public int getNumberOfParticles() {
        return this.getParticles().size();
    }
}
